#include "../Inc/LinearList.h"
#include <stdlib.h>
#include <stdio.h>

status LinearList_Init(linear_list_t *list) {
    list->element = (user_linear_list_elment_t *)malloc(LINEAR_LIST_MAX_SIZE*sizeof(user_linear_list_elment_t));
    if (!list->element) {
        printf("Fail to allocate storage space.\n");
        return FAIL;
    }

    list->length = 0;

    printf("Linear list init successfully.\n");
    return OK;
}

status LinearList_Deinit(linear_list_t *list) {
    free(list->element);

    list->length = 0;

    printf("Linear list deinit successfully.\n");
    return OK;
}

status LinearList_GetElement(linear_list_t *list, unsigned int index, user_linear_list_elment_t *element) {
    if ((list->length < 1) || (list->length > LINEAR_LIST_MAX_SIZE)) {
        printf("List is NULL or it exceeds the maximum length.\n");
        return FAIL;
    }

    *element = list->element[index-1];

    return OK;
}

// FIXME: Wrong output, it should be an index
status LinearList_LocateElement(linear_list_t *list, user_linear_list_elment_t element) {
    if ((list->length < 1) || (list->length > LINEAR_LIST_MAX_SIZE)) {
        printf("List is NULL or it exceeds the maximum length.\n");
        return FAIL;
    }

    for (size_t i = 0; i < list->length; i++) {
        if (list->element[i].value == element.value) {
            printf("Find element in index %d.\n", i);
            return OK;
        }
    }

    printf("There is no %d in this linear list. Please check it.\n", element.value);
    return FAIL;
}

status LinearList_InsertElement(linear_list_t *list, unsigned int index, user_linear_list_elment_t element) {
    if ((list->length < 1) || (list->length > LINEAR_LIST_MAX_SIZE)) {
        printf("List is NULL or it exceeds the maximum length.\n");
        return FAIL;
    }
    else if (list->length == LINEAR_LIST_MAX_SIZE) {
        printf("List reaches the maximum length. Please delete some elements.\n");
        return FAIL;
    }

    if (index < 0 || index > LINEAR_LIST_MAX_SIZE) {
        printf("Index cannot be negative or exceed the maximum length.\n");
        return FAIL;
    }

    for (size_t i = list->length; i > index; i--) {
        list->element[i] = list->element[i-1];
    }
    list->element[index] = element;
    list->length++;

    printf("Add %d to the index %d of the list successfully.\n", list->element[index].value, index);
    return OK;
}

status LinearList_DeleteElement(linear_list_t *list, unsigned int index) {
    if ((list->length < 1) || (list->length > LINEAR_LIST_MAX_SIZE)) {
        printf("List is NULL or it exceeds the maximum length.\n");
        return FAIL;
    }

    if (index < 0 || index > LINEAR_LIST_MAX_SIZE) {
        printf("Index cannot be negative or exceed the maximum length.\n");
        return FAIL;
    }
    
    for (size_t i = index; i < list->length; i++) {
        list->element[i] = list->element[i+1];
    }
    list->length++;
    
    printf("Delete element from the index %d of the list successfully.\n", index);
    return OK;
}

void LinearList_Test(void) {
    linear_list_t list;
    LinearList_Init(&list);

    for (size_t i = 0; i < 10; i++) {
        list.element[i].value = i;
    }
    list.length = 10;

    user_linear_list_elment_t insert_element = {
        .value = 111
    };

    LinearList_InsertElement(&list, 2, insert_element);

    user_linear_list_elment_t find_element = {
        .value = 111
    };

    LinearList_LocateElement(&list, find_element);

    LinearList_DeleteElement(&list, 2);

    LinearList_LocateElement(&list, find_element);

    LinearList_Deinit(&list);
}
